Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attempt to improve plug call exception handling and logging #398

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

grzuy
Copy link

@grzuy grzuy commented Sep 16, 2024

Supersedes #396.

- Telementry events
  - Also emit span for throw
  - Also emit span for exit

- Logger
  - Lets logger handlers know about the original crash reason when handling bandit errors
@grzuy grzuy changed the title More complete exception handling and logging Attempt to improve exception handling and logging Sep 16, 2024
@grzuy grzuy mentioned this pull request Sep 16, 2024
Comment on lines 48 to 49
rescue
error -> handle_error(error, __STACKTRACE__, transport, span, opts)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it's redundant with the catch block below (raise being realized by try/catch internally), but I don't think it's part of official spec; can we leave this clause here to make it explicit? Alternately, if the language is authoritative on this, that's fine too.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right.

Despite working like that doesn't seem to be actually documented in https://hexdocs.pm/elixir/try-catch-and-rescue.html that you can catch all (including :error) with just catch.

Re-instating the rescue clause just in case.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. It sounds like it's an implementation detail then, so we're safer to be explicit in case they ever change it in the language.

* `reason`: The exception, throw value or exit reason which caused this unexpected termination
* `stacktrace`: The stacktrace of the location which caused this unexpected termination

* `[:bandit, :request, :exception]` (DEPRECATED)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realize that exception is (and always has been) the wrong term here, but I've deliberately been using it to mirror the naming conventions of :telemetry.span/3.

Copy link
Author

@grzuy grzuy Sep 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha.

I only introduced a new event name just to not break the shape of the actual one when supporting more kinds.

Updating back to only [:bandit, :request, :exception], with the correct kind and reason field, and maybe keeping the exception field in case is_exception(reason), so that this doesn't break peoples telemetry handlers listening and matching on that metadata field.

It will break anyone matching on kind: :exit and exception: exception at the same time. This will now be corrected to kind: :error and exception: exception.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fine

@mtrudel
Copy link
Owner

mtrudel commented Sep 16, 2024

A couple of changes requested to keep things consistent and explicit; other than those changes the rest of this looks great!

@grzuy
Copy link
Author

grzuy commented Sep 17, 2024

Fixed format.

Can't reproduce locally the protocol_test.exs failures happening here, though.

@grzuy grzuy changed the title Attempt to improve exception handling and logging Attempt to improve plug call exception handling and logging Sep 17, 2024
@grzuy
Copy link
Author

grzuy commented Sep 17, 2024

@mtrudel Just realized that Bandit was originally taking the approach of re-raising plug call errors in 1.4 instead of just "logging or silence" with changes in 1.5 with https://github.com/mtrudel/bandit/pull/342/files#diff-68626306df11d3e10964941997c6cdafbf587a9ec7de087141840655a47a1855L65.

Curious about the reason not to continue re-raising?

Similar to what plug_cowboy does...

In case there's the possibility of introducing re-raise again, this pull request could be re-worked.

@grzuy
Copy link
Author

grzuy commented Sep 17, 2024

Reading this thread (https://groups.google.com/g/elixir-lang-core/c/pWz-uTVMEVM/m/QGXncxD1AQAJ) also got me thinking about it.

@mtrudel
Copy link
Owner

mtrudel commented Sep 17, 2024

Similar to what plug_cowboy does...

Interesting! It seems like they're using exactly the 'catch :error types' convention I raised above, such that exceptions are in fact re-raising. I think when I'd read the plug_cowboy implementation originally I saw the catch and assumed that handling was only for idiomatic throw/catch usage (which the current Bandit implementation handles).

The main purpose of that PR was to ensure that logging of errors takes into consideration the accompanying result code (ie: only log errors that get raised with a 500..599 response code). This generally means that we do the logging ourselves (as we do in that PR) instead of reraising and letting the runtime log it

All of which is to say that I think we're doing the right thing by not re-raising?

@grzuy
Copy link
Author

grzuy commented Sep 18, 2024

Mmm... not sure to he honest.

I'm exploring the "re-raising approach" in a separate branch to compare.

I'll let you know how it goes.

@grzuy
Copy link
Author

grzuy commented Sep 18, 2024

I'm exploring the "re-raising approach" in a separate branch to compare.

Opening draft with what I got from playing with that alternative approach: #400.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants